﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.Office.Interop.Word;

namespace WordMaster
{
    public partial class MainForm : Form
    {
        // 待处理的任务
        private List<TaskInfo> tasks = new List<TaskInfo>();

        //
        private bool isProcessing = false;

        #region 方法
        //
        public MainForm()
        {
            InitializeComponent();
            //
            RefreshTaskListBox();
        }

        //
        public void RefreshTaskListBox()
        {
            taskListBox.Items.Clear();
            taskListBox.Items.AddRange(tasks.ToArray());
            EnableButtons();
        }

        //
        public void EnableButtons()
        {
            btnBatch.Enabled = !isProcessing && CanHandle();
            btnRemoveFiles.Enabled = fileListBox.SelectedItems.Count > 0;
            btnClearFiles.Enabled = fileListBox.Items.Count > 0;
            btnRemoveTasks.Enabled = taskListBox.SelectedItems.Count > 0;
            btnClearTasks.Enabled = taskListBox.Items.Count > 0;
            progressBar1.Maximum = fileListBox.Items.Count;
            lblFileCount.Text = "(" + fileListBox.Items.Count.ToString() + ")";
            lblTaskCount.Text = "(" + taskListBox.Items.Count.ToString() + ")";
        }

        //
        public void AddFiles()
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                fileListBox.Items.AddRange(this.openFileDialog1.FileNames);
                EnableButtons();
            }
        }

        public object[] MergeParameters(object[] parms1, object[] parms2)
        {
            int len1 = parms1 == null ? 0 : parms1.Length;
            int len2 = parms2 == null ? 0 : parms2.Length;
            if (len1 + len2 > 0)
            {
                object[] result = new object[len1 + len2];
                if (parms1 != null) {
                    parms1.CopyTo(result, 0);
                }
                if (parms2 != null)
                {
                    parms2.CopyTo(result, len1);
                }
                return result;
            }
            return null;
        }

        //
        public void HandleTasks(Document wordDoc)
        {
            foreach(var task in tasks)
            {
                if (task.Name == TaskTypes.PageSetupTopMargin ||
                    task.Name == TaskTypes.PageSetupBottomMargin ||
                    task.Name == TaskTypes.PageSetupLeftMargin ||
                    task.Name == TaskTypes.PageSetupRightMargin ||
                    task.Name == TaskTypes.PageSetupHeaderDistance ||
                    task.Name == TaskTypes.PageSetupFooterDistance)
                {
                    var parms = MergeParameters(new object[] { wordDoc }, task.Parameters);
                    CallMethod(task.Name, parms);
                } else
                {
                    SectionForEach(wordDoc, task);
                }
            }
            
        }

        //
        private void SectionForEach(Document wordDoc, TaskInfo task)
        {
            foreach (Section section in wordDoc.Sections)
            {
                var parms = MergeParameters(new object[] { section, wordDoc }, task.Parameters);
                CallMethod(task.Name, parms);
            }
        }

        #region 任务处理方法
        public void SetPageTopMargin(Document wordDoc, float value)
        {
            wordDoc.PageSetup.TopMargin = wordDoc.Application.CentimetersToPoints(value);
        }

        public void SetPageBottomMargin(Document wordDoc, float value)
        {
            wordDoc.PageSetup.BottomMargin = wordDoc.Application.CentimetersToPoints(value);
        }

        public void SetPageLeftMargin(Document wordDoc, float value)
        {
            wordDoc.PageSetup.LeftMargin = wordDoc.Application.CentimetersToPoints(value);
        }

        public void SetPageRightMargin(Document wordDoc, float value)
        {
            wordDoc.PageSetup.RightMargin = wordDoc.Application.CentimetersToPoints(value);
        }

        public void SetHeaderDistance(Document wordDoc, float value)
        {
            wordDoc.PageSetup.HeaderDistance = wordDoc.Application.CentimetersToPoints(value);
        }

        public void SetFooterDistance(Document wordDoc, float value)
        {
            wordDoc.PageSetup.FooterDistance = wordDoc.Application.CentimetersToPoints(value);
        }

        // 添加页码
        public void AddPageNumber(Section section, string fontName = "Times New Roman", int fontSize = 9)
        {
            Range footerRange = section.Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
            footerRange.Font.Size = fontSize;
            footerRange.Font.Name = fontName;
            footerRange.Fields.Add(footerRange, WdFieldType.wdFieldPage);
            footerRange.Collapse(WdCollapseDirection.wdCollapseEnd);
            footerRange.Text = " / ";
            footerRange.Collapse(WdCollapseDirection.wdCollapseEnd);
            footerRange.Fields.Add(footerRange, WdFieldType.wdFieldNumPages);
            footerRange.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
        }

        // 移除页眉
        public void RemoveHeader(Section section, Document wordDoc)
        {
            section.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.Delete();
            section.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.Select();
            wordDoc.ActiveWindow.Selection.ClearFormatting();
            //section.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.ParagraphFormat.Borders[WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone;
        }

        // 移除页脚
        public void RemoveFooter(Section section, Document wordDoc)
        {
            section.Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.Delete();
            section.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.Select();
            wordDoc.ActiveWindow.Selection.ClearFormatting();
        }
        #endregion

        // 判断是否满足执行批处理的条件
        public bool CanHandle()
        {
            return this.fileListBox.Items.Count > 0 && this.taskListBox.Items.Count > 0;
        }

        // 设置进度显示文本
        public void SetProgressBarValue(int value)
        {
            lblProgress.Text = value.ToString() + " / " + fileListBox.Items.Count.ToString();
            progressBar1.Value = value;
        }

        // 动态调用方法
        public void CallMethod(string name, object[] parms)
        {
            MethodInfo method = GetType().GetMethod(name);
            method.Invoke(this, parms);

            //MethodInfo method = this.GetType().GetMethod(funcName);
            //Func<bool> func = (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), this, method);
            //func();
        }
        #endregion

        #region 事件
        // 添加文件
        private void menuItemAddFiles_Click(object sender, EventArgs e)
        {
            AddFiles();
        }

        // 清空文件列表框
        private void btnClearFiles_Click(object sender, EventArgs e)
        {
            fileListBox.Items.Clear();
            EnableButtons();
        }

        // 从文件列表框中移除选中的文件
        private void btnRemoveFiles_Click(object sender, EventArgs e)
        {
            var selectedItems = fileListBox.SelectedItems;
            for(int i = 0; i < selectedItems.Count; i++)
            {
                fileListBox.Items.Remove(selectedItems[i]);
            }
        }

        // 从任务列表框中移除选中的任务
        private void btnRemoveTasks_Click(object sender, EventArgs e)
        {
            var selectedItems = taskListBox.SelectedItems;
            for (int i = selectedItems.Count - 1; i >= 0; i--)
            {
                int index = taskListBox.Items.IndexOf(selectedItems[i]);
                taskListBox.Items.RemoveAt(index);
                tasks.RemoveAt(index);
            }
            RefreshTaskListBox();
        }

        // 清空任务列表框
        private void btnClearTasks_Click(object sender, EventArgs e)
        {
            tasks.Clear();
            RefreshTaskListBox();
        }

        // 开始批量处理
        private void btnBatch_Click(object sender, EventArgs e)
        {
            SetProgressBarValue(0);
            isProcessing = true;
            EnableButtons();
            Microsoft.Office.Interop.Word.Application wordApp = null;
            try
            {
                wordApp = new Microsoft.Office.Interop.Word.Application();
                wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone;

                Microsoft.Office.Interop.Word.Document wordDoc;
                int i = 0;
                foreach (var path in this.fileListBox.Items)
                {
                    wordDoc = wordApp.Documents.Open(path);

                    //
                    HandleTasks(wordDoc);

                    wordDoc.Close(WdSaveOptions.wdSaveChanges);
                    SetProgressBarValue(++i);
                }

                isProcessing = false;
                EnableButtons();
                MessageBox.Show("处理完成！", "温馨提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                isProcessing = false;
                MessageBox.Show(ex.Message);
            }
            finally
            {
                isProcessing = false;
                EnableButtons();
                if (wordApp != null)
                {
                    wordApp.Quit();
                }
            }
        }

        // 页面设置-页边距
        private void MenuItemPageSetupMargin_Click(object sender, EventArgs e)
        {
            PageSetupMarginForm frm = new PageSetupMarginForm();
            DialogResult result = frm.ShowDialog(this);
            if(result == DialogResult.OK)
            {
                //MessageBox.Show(frm.Tasks.Count.ToString());
                tasks.AddRange(frm.Tasks);
                RefreshTaskListBox();
            }
        }

        // 页面设置-页眉页脚距离
        private void MenuItemPageSetupHeaderFooterDistance_Click(object sender, EventArgs e)
        {
            PageSetupDistanceForm frm = new PageSetupDistanceForm();
            DialogResult result = frm.ShowDialog();
            if(result == DialogResult.OK)
            {
                // MessageBox.Show(frm.Tasks.Count.ToString());
                tasks.AddRange(frm.Tasks);
                RefreshTaskListBox();
            }
        }

        // 添加 添加页码 的任务
        private void MenuItemAddPageNumber_Click(object sender, EventArgs e)
        {
            //tasks.Add(new TaskInfo(
            //    TaskTypes.PageNumberAdd, 
            //    "添加页码", 
            //    "向所有页面底部添加居中的 x/y 形式的页码"));
            //RefreshTaskListBox();
            PageNumberForm frm = new PageNumberForm();
            DialogResult result = frm.ShowDialog();
            if (result == DialogResult.OK)
            {
                tasks.AddRange(frm.Tasks);
                RefreshTaskListBox();
            }
        }

        // 添加 移除页眉 的任务
        private void MenuItemRemoveHeader_Click(object sender, EventArgs e)
        {
            tasks.Add(new TaskInfo(
                TaskTypes.HeaderRemove, 
                "移除页眉", 
                "移除所有页面的页眉"));
            RefreshTaskListBox();
        }

        // 添加 移除页脚 的任务
        private void MenuItemRemoveFooter_Click(object sender, EventArgs e)
        {
            tasks.Add(new TaskInfo(
                TaskTypes.FooterRemove, 
                "移除页脚", 
                "移除所有页面的页脚"));
            RefreshTaskListBox();
        }

        //
        private void fileListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            EnableButtons();
        }

        //
        private void taskListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            EnableButtons();
        }

        //
        private void btnAddFiles_Click(object sender, EventArgs e)
        {
            AddFiles();
        }
        #endregion
    }
}
